#pragma once 
#include "connection.hpp"
#include "addr.hpp"
class Channel : public Connection
{

public:
  Channel(int fd, inetaddr client) : _sockfd(fd), _client(client)
  {
    // 设置边沿触发与非阻塞
    Setevents(EPOLLIN | EPOLLET);
    set_nonblock(_sockfd);
  }

  void Recver() override
  {
    char buff[1024];

    while (1)
    {
      int n = recv(_sockfd, buff, sizeof(buff), 0);
      if (n > 0)
      {
        buff[n] = 0;
        _inbuff += buff;
      }

      else if (n == 0)
      {
        // 说明可能对应真正的接收缓冲区被关闭了，异常处理
        Excepter();
        return;
      }

      else
      {
        if (errno == EAGAIN || errno == EWOULDBLOCK)
          break;
        else if (errno == EINTR) // 信号中断
          continue;
        else
        { // 出现意外的异常：
          Excepter();
          return;
        }
      }
    }
    if(!_inbuff.empty()){
       _outbuff=_func(_inbuff);//往上层协议层传递，最后通过业务层完成处理再借助协议层返回对应串
    }

    if(!_outbuff.empty()){
      Sender();
      //CareReadWrite(_sockfd,1,1);//下一轮epoll后再发送明显效率低(因为它需要把对的写缓冲区加入epoll模型，等到下一次epollwait时候才能发送，也就是调用Sender)
    }
  }
  void Sender()override{

    while (1)
    {
      int n = send(_sockfd, _outbuff.c_str(), _outbuff.size(), 0);//不能sizeof(_outbuff.c_str())
      if (n > 0)
      {
        //这里有可能n不等于_outbuff的大小，因为可能对应的真正的发送缓冲区满了
        _outbuff.erase(0,n);
        //如果最后一次发送完了
        if(_outbuff.empty()) break;
      
      }

      else if (n == 0)
      {
         //说明对方把链接双向关闭了
          break;
      }

      else
      {
        if (errno == EAGAIN || errno == EWOULDBLOCK)//说明发送缓冲区没有位置了，给它用epoll关心上，后续空出来接着从outbuff中发送
          break;
        else if (errno == EINTR) // 信号中断
          continue;
        else
        { // 出现意外的异常：
          Excepter();
          return;
        }
      }
    }

  //分为outbuff中发送完了，或者由于发送缓冲区满了导致outbuff没发完：
  if(!_outbuff.empty()) {
    Getowner()->CareReadWrite(_sockfd,1,1);
  }
  else {
    Getowner()->CareReadWrite(_sockfd,1,0);
  }

  }
  void Excepter() override
  {
    Getowner()->Delconnection(_sockfd);
  }
  int GetSockFd()
  {
    return _sockfd;
  }

  ~Channel() {}

private:
  int _sockfd;
  inetaddr _client;
  string _inbuff;  // 虚拟接收缓冲区
  string _outbuff; // 虚拟发送缓冲区
};